import 'dart:io';
import 'dart:typed_data';
import 'dart:ui';

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_demo/generated/assets.dart';
import 'package:flutter_demo/pages/custom/custom_paint_page.dart';
import 'package:flutter_demo/pages/page_with_title.dart';
import 'package:flutter_demo/widgets/app_widgets.dart';
import 'package:flutter_iconpicker/IconPicker/icons.dart';
import 'package:flutter_iconpicker/Models/configuration.dart';
import 'package:flutter_iconpicker/flutter_iconpicker.dart';
import 'package:path_provider/path_provider.dart';

import '../../conf/m3.dart';
import '../container/fitted_box_page.dart';

class ImagePage extends PageWithTitle {
  const ImagePage({super.key}) : super("图像(Icon、Image)");

  @override
  List<Widget> buildContentWidgets(BuildContext context) {
    return const [
      PrimaryTitle("简介"),
      BodyText("Ui设计主要由由文本与图像构成，在Flutter中提供以下组件加载图像"),
      AppSpacer.large,
      _IconExample(),
      AppSpacer.mini,
      UlItem("Icon"),
      BodyText("主要用于显示矢量图标，常用于按钮、标记、导航等，优势是缩放不失真、可以设置色调，"
          "是个轻量级的组件，除了内置图标，还以使用第三方库（如FontAwesomeIcons）或者自定"
          "IconData，它有以下常用属性"),
      Row(
        children: [
          PrimaryHeaderLabelText("size", "指定组件尺寸"),
          Icon(Icons.ten_k, size: 40),
          Icon(CupertinoIcons.book_solid, size: 40),
        ],
      ),
      Row(
        children: [
          PrimaryHeaderLabelText("color", "指定图标色调"),
          Icon(Icons.ten_k, color: Colors.deepOrangeAccent),
        ],
      ),
      Wrap(
        children: [
          PrimaryHeaderLabelText("shadows", "指定阴影效果，它可以同时设置多个阴影"),
          Icon(
            Icons.ten_k,
            shadows: [
              Shadow(color: Colors.grey, offset: Offset(2, 2), blurRadius: 5)
            ],
          ),
        ],
      ),
      Wrap(
        children: [
          PrimaryHeaderLabelText(
            "semanticLabel",
            "语义标签，用于无障碍功能，类似安卓的描述文本",
          ),
          Icon(Icons.ten_k, semanticLabel: "10K"),
        ],
      ),
      AppSpacer.large,
      _ImageExample(),
      UlItem("Image"),
      BodyText("主要用于内容图片展示，可以设置缩放模式，封装了内部资源、内存、网络、存储的图片"
          "加载过程，它本身也是可以用于加载像素图像和矢量图像"),
      PrimaryHeaderLabelText("资源加载方式"),
      LabelText("    - Image.asset 加载APP内置图片"),
      LabelText("    - Image.network 加载网络图片"),
      LabelText("    - Image.memory 加载内存图片"),
      LabelText("    - Image.file 加载本地图片"),
      AppSpacer.normal,
      PrimaryHeaderLabelText(
        "width height",
        "指定组件尺寸",
        "若不指定则默认是按约束和图片原始大小来决定（注意，它指一图片像素对应一逻辑像素，而不"
            "是一物理像素，优势是在不同屏幕密度的设备上有一致的视觉大小，缺点是图片可能缩放过"
            "渡导致模糊，我倒是觉得这个比android原生的合理）",
        "若只指定一个属性，另一个属性将根据图片内容的实际宽高比决定",
        "若指定两个属性，此时就需要参考fit属性来设置图片的填充模式了",
      ),
      AppSpacer.normal,
      PrimaryHeaderLabelText(
        "scale",
        "缩放，它指一逻辑像素对应scale倍的图像像素（宽与高），在不设置组件宽高时起作用",
      ),
      AppSpacer.normal,
      PrimaryHeaderLabelText("fit", "填充模式"),
      LabelText("    - fill 拉伸填满组件"),
      LabelText("    - contain 居中等比缩放图片到组件边缘，使组件可以完整包含图片，但组件可"
          "能有空白区域"),
      LabelText("    - cover 居中等比缩放图片至完全盖住组件，但图片可能被裁剪掉一部分"),
      LabelText("    - fitWidth 居中等比缩放图片至填满组件宽度"),
      LabelText("    - fitHeight 居中等比缩放图片至填满组件高度"),
      LabelText("    - scaleDown 类似contain，但它只能缩小显示而不会放大，也就是图片比组"
          "件小会出现四边都留白而不像contain两边留白"),
      NoticeText("Image也是支持对齐设置的，填充效果可以参考FittedBox"),
      PageLink(FittedBoxPage()),
      AppSpacer.normal,
      PrimaryHeaderLabelText("color", "色调设置，结合混合模式来设置颜色叠加效果"),
      PrimaryHeaderLabelText(
        "colorBlendMode",
        "颜色混合模式，默认srcIn表示取上下图层重叠部分并采用上层像素颜色",
      ),
      PrimaryHeaderLabelText(
        "opacity",
        "透明度设置，本身是一个动画对象，用于避免使用FadeTransition导致使用2倍内存（"
            "因为Flutter的分层渲染机制，即动静分离图层，静态图层采用离屏渲染来缓存最新画面，"
            "实现高效更新动态图层，动画API会使动画组件下层的组件缓存绘制结果），直接使用此属"
            "性来避免分层渲染，若不需要动画效果可以使用AlwaysStoppedAnimation，它直接固"
            "定动画值且不做任何动画更新",
      ),
      PrimaryHeaderLabelText(
        "semanticLabel",
        "语义标签，用于无障碍功能，类似安卓的描述文本",
      ),
      PrimaryHeaderLabelText(
        "frameBuilder",
        "图像帧构建器，用于像gif或者执行动画时，在每次刷帧对图像组件进行一个包装处理",
      ),
      PrimaryHeaderLabelText(
        "loadingBuilder",
        "加载图片过程中的占位组件，还贴心给了加载进度，这在加载网络和本地资源时起效果",
      ),
      PrimaryHeaderLabelText("errorBuilder", "图片加载错误时显示的组件"),
      PrimaryHeaderLabelText(
        "cacheWidth cacheHeight",
        "图片解码后会压缩到指定宽高进行显示和缓存",
      ),
      PrimaryHeaderLabelText("headers", "加载网络图片时携带的请求头"),
    ];
  }
}

class _IconExample extends StatefulWidget {
  const _IconExample();

  @override
  State<StatefulWidget> createState() {
    return _IconExampleState();
  }
}

class _IconExampleState extends State<_IconExample> {
  final materialIcons = FIPIconManager.getSelectedPack(IconPack.material);
  Map<String, IconPickerIcon>? pickedMaterialIcon;

  final cupertinoIcons = FIPIconManager.getSelectedPack(IconPack.cupertino);
  Map<String, IconPickerIcon>? pickedCupertinoIcon;

  @override
  Widget build(BuildContext context) {
    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        const BodyText("Flutter内置图标"),
        AppSpacer.normal,
        Row(
          children: [
            const LabelText("Material图标（安卓、window、linux、web设计风格）"),
            AppSpacer.normal,
            InkWell(
              onTap: () {
                showIconPicker(context,
                    configuration: const SinglePickerConfiguration(
                        iconPackModes: [IconPack.material])).then((pick) {
                  setState(() {
                    if (pick == null) {
                      pickedMaterialIcon = null;
                    } else {
                      pickedMaterialIcon = {pick.name: pick};
                    }
                  });
                });
              },
              child: Text(
                "搜索",
                style: TextStyle(
                    color: Theme.of(context).colorScheme.primary,
                    decoration: TextDecoration.underline,
                    decorationStyle: TextDecorationStyle.solid),
              ),
            ),
          ],
        ),
        buildIconGridView(context, pickedMaterialIcon ?? materialIcons),
        AppSpacer.normal,
        Row(
          children: [
            const LabelText("Cupertino图标（ios、macOs设计风格）"),
            AppSpacer.normal,
            InkWell(
              onTap: () {
                showIconPicker(context,
                    configuration: const SinglePickerConfiguration(
                        iconPackModes: [IconPack.cupertino])).then((pick) {
                  setState(() {
                    if (pick == null) {
                      pickedCupertinoIcon = null;
                    } else {
                      pickedCupertinoIcon = {pick.name: pick};
                    }
                  });
                });
              },
              child: Text(
                "搜索",
                style: TextStyle(
                    color: Theme.of(context).colorScheme.primary,
                    decoration: TextDecoration.underline,
                    decorationStyle: TextDecorationStyle.solid),
              ),
            ),
          ],
        ),
        buildIconGridView(context, pickedCupertinoIcon ?? cupertinoIcons),
      ],
    );
  }

  Widget buildIconGridView(
      BuildContext context, Map<String, IconPickerIcon> namedIcons) {
    final list = namedIcons.entries.toList();
    return Container(
      height: 300,
      padding: const EdgeInsetsDirectional.all(M3.paddingM),
      decoration: BoxDecoration(
        color: Theme.of(context).colorScheme.surfaceContainer,
        borderRadius: M3.connerRadiusMedium,
      ),
      child: GridView.builder(
        scrollDirection: Axis.horizontal,
        itemCount: list.length,
        gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
          crossAxisCount: 3,
          mainAxisSpacing: M3.paddingS,
          crossAxisSpacing: M3.paddingS,
          childAspectRatio: 1,
        ),
        itemBuilder: (context, index) {
          return AspectRatio(
            aspectRatio: 1,
            child: Container(
              decoration: BoxDecoration(
                color: Theme.of(context).colorScheme.outlineVariant,
                borderRadius: M3.connerRadiusMedium,
              ),
              child: Column(
                mainAxisAlignment: MainAxisAlignment.center,
                children: [
                  Icon(list[index].value.data),
                  Text(list[index].key),
                ],
              ),
            ),
          );
        },
      ),
    );
  }
}

class _ImageExample extends StatefulWidget {
  const _ImageExample();

  @override
  State<StatefulWidget> createState() {
    return _ImageExampleState();
  }
}

class _ImageExampleState extends State<_ImageExample> {
  Widget? localImage;
  Widget? memoryImage;

  @override
  void initState() {
    super.initState();
    if (memoryImage == null) {
      generateMemoryImage().then((data) {
        setState(() {
          memoryImage = Image.memory(
            data,
            width: 80,
          );
        });
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        Row(
          children: [
            const Text("内置资源图片"),
            Image.asset(
              Assets.imagesBenxi,
              width: 80,
            ),
          ],
        ),
        Row(
          children: [
            const Text("网络图片"),
            Image.network(
              "https://i0.hdslb.com/bfs/archive/a6fc20e8360913e8c796df1def661bf1d7f1b9c8.png",
              width: 80,
              color: Theme.of(context).primaryColor,
              loadingBuilder: (context, child, loadingProgress) {
                if (loadingProgress != null) {
                  return const CircleLoading();
                } else {
                  return child;
                }
              },
              errorBuilder: (context, error, stackTrace) {
                return const Text("network error");
              },
            ),
          ],
        ),
        AppSpacer.mini,
        Row(
          children: [
            const Text("内存图片"),
            memoryImage ?? const CircleLoading(),
          ],
        ),
        AppSpacer.mini,
        Row(
          children: [
            const Text("本地图片"),
            localImage ?? const CircleLoading(),
          ],
        ),
      ],
    );
  }

  Future<Uint8List> generateMemoryImage() async {
    //类似Android的bitmap，创建canvas进行绘制
    final pictureRecorder = PictureRecorder();
    final canvas = Canvas(pictureRecorder, const Rect.fromLTRB(0, 0, 200, 200));
    canvas.drawColor(Colors.yellow, BlendMode.src);
    //endRecording得到Picture,将其转化为image
    final image = await pictureRecorder.endRecording().toImage(200, 200);
    //将image编码为png图像数据
    final byteData = await image.toByteData(format: ImageByteFormat.png);
    //取得png数据转为字节数组
    final bytes = byteData!.buffer.asUint8List();
    await writeToFile(bytes);
    //取得png数据转为字节数组
    return bytes;
  }

  writeToFile(Uint8List bytes) async {
    //取得原生平台的app沙盒文件路径，app默认有权限可以读取自己沙盒路径，若要读取公共目录则需要权
    // 限支持，但一般不建议直接访问
    final filePath = await getApplicationSupportDirectory();
    // 重新创建文件并写入数据
    final localImagePath = "${filePath.path}/image_page/localImage.png";
    final File file = File(localImagePath);
    if (file.existsSync()) {
      file.delete();
    }
    //recursive可以递归创建上级路径
    file.createSync(recursive: true);
    await file.writeAsBytes(bytes);
    localImage = Image.file(
      file,
      width: 80,
    );
  }
}
